package api

import (
	"fmt"
	"math/rand"
	"net/http"
	db "slgw_web/application/gormdb"
	"slgw_web/serial/pac"
	"slgw_web/serial/util"

	"openzbox.com/frame/echo"
	models "openzbox.com/frame/echo/models/sl_gw01"
	"openzbox.com/frame/echo/response"
	"openzbox.com/misc/ps/load"
	"openzbox.com/utils"

	//"syscall"
	"time"
	//"unsafe"

	//"openzbox.com/utils"
	"openzbox.com/misc/ps/cpu"
	"openzbox.com/misc/ps/disk"
	"openzbox.com/misc/ps/host"
	"openzbox.com/misc/ps/mem"
	_net "openzbox.com/misc/ps/net"
)

type LSysInfo struct {
	/*MemAll         uint64
	MemFree        uint64
	MemUsed        uint64
	MemUsedPercent float64

	Days           int64
	Hours          int64
	Minutes        int64
	Seconds        int64

	CpuUsedPercent float64
	OS             string
	Arch           string
	CpuCores       int
	*/
	Meminfo    *mem.VirtualMemoryStat `json:"meminfo"`
	Cpuinfo    []cpu.InfoStat         `json:"cpuinfo"`
	Hostinfo   *host.InfoStat         `json:"hostinfo"`
	Diskinfo   *disk.UsageStat        `json:"diskinfo"`
	Iocounts   []_net.IOCountersStat  `json:"iocounts"`
	Pids       []int32                `json:"pids"`
	Interfaces _net.InterfaceStatList `json:"interfaces"`
	Load       *load.AvgStat          `json:"load"`
}

// Handler
func Sysinfo(c echo.Context) error {
	info := getSysInfo()
	//fmt.Println(info )
	return c.JSON(http.StatusOK, info)
}

func getSysInfo() (info LSysInfo) {

	//unit := uint64(1024 * 1024) // MB

	v, _ := mem.VirtualMemory()
	info.Meminfo = v

	//info.Pids , _ = process.Pids();
	//fmt.Println(_net.Connections("all"));
	info.Interfaces, _ = _net.Interfaces()
	load, _ := load.Avg()
	info.Load = load

	/*info.MemAll = v.Total
	info.MemFree = v.Free
	info.MemUsed = info.MemAll - info.MemFree
	// 注：使用SwapMemory或VirtualMemory，在不同系统中使用率不一样，因此直接计算一次
	info.MemUsedPercent = utils.RoundFloat64 (float64(info.MemUsed) / float64(info.MemAll) * 100.0 ,2);// v.UsedPercent
	info.MemAll /= unit
	info.MemUsed /= unit
	info.MemFree /= unit*/
	/*
		info.OS = runtime.GOOS
		info.Arch = runtime.GOARCH
		info.CpuCores = runtime.GOMAXPROCS(0)

		// 获取200ms内的CPU信息，太短不准确，也可以获几秒内的，但这样会有延时，因为要等待

	*/
	// 获取开机时间
	/*boottime, _ := host.BootTime()
	ntime := time.Now().Unix()
	btime := time.Unix(int64(boottime), 0).Unix()
	deltatime := ntime - btime

	info.Seconds = int64(deltatime)
	info.Minutes = info.Seconds / 60
	info.Seconds -= info.Minutes * 60
	info.Hours = info.Minutes / 60
	info.Minutes -= info.Hours * 60
	info.Days = info.Hours / 24
	info.Hours -= info.Days * 24
	*/
	cc, _ := cpu.Percent(time.Millisecond*200, false)

	c, _ := cpu.Info()
	c[0].CpuUsedPercent = utils.RoundFloat64(cc[0], 2)

	info.Cpuinfo = c
	h, _ := host.Info()
	info.Hostinfo = h

	d, _ := disk.Usage("/")
	info.Diskinfo = d

	nv, _ := _net.IOCounters(true)
	info.Iocounts = nv

	/*d, _ := disk.Usage("/")
	nv, _ := _net.IOCounters(true)
	physicalCnt, _ := cpu.Counts(false)
	logicalCnt, _ := cpu.Counts(true)
	if len(c) > 1 {
		for _, sub_cpu := range c {
			modelname := sub_cpu.ModelName
			cores := sub_cpu.Cores
			fmt.Printf("CPUs: %v   %v cores \n", modelname, cores)
		}
	} else {
		sub_cpu := c[0]
		modelname := sub_cpu.ModelName
		cores := sub_cpu.Cores
		fmt.Printf("CPU: %v   %v cores \n", modelname, cores)
	}
	fmt.Printf("physical count:%d logical count:%d\n", physicalCnt, logicalCnt)
	fmt.Printf("HD: %v MB Free: %v MB Usage:%.2f%%\n", d.Total/1024/1024, d.Free/1024/1024, d.UsedPercent)
	fmt.Printf("OS: %v(%v) %v\n", n.Platform, n.PlatformFamily, n.PlatformVersion)
	fmt.Printf("Hostname: %v\n", n.Hostname)
	fmt.Printf("Network: %v bytes / %v bytes\n", nv[0].BytesRecv, nv[0].BytesSent)
	*/
	//GetMACAddress()

	/*r ,err :=utils.Ping("www.baidu.com")
	fmt.Printf("%v %s\r\n",r,err)
	*/
	return info

}

// 获取系统信息
func GetSystemInfo(ctx echo.Context) error {
	//定义文章结构体切片
	systemInfo := models.SystemInfo{}
	db := db.GetDB()
	db.First(&systemInfo)
	return response.SuccessResult(systemInfo, ctx)

}

// 修改系统信息
func EditSystemInfo(ctx echo.Context) error {
	var req models.EditSystemInfoRequest
	if err := ctx.Bind(&req); err != nil {
		// 处理参数绑定错误
		//	ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return response.FailResult(1, err.Error(), ctx)

	}
	db := db.GetDB()
	if req.SystemInfo.ID != 0 {
		//修改
		updateFields := map[string]interface{}{
			"IsRereported":   req.SystemInfo.IsRereported,
			"IsWatchdog":     req.SystemInfo.IsWatchdog,
			"ComType":        req.SystemInfo.ComType,
			"ATType":         req.SystemInfo.ATType,
			"TaskSetTimeUrl": req.SystemInfo.TaskSetTimeUrl,
			// 添加其他需要更新的字段
		}
		if err := db.Model(&models.SystemInfo{}).Where("id = ?", req.SystemInfo.ID).Updates(updateFields).Error; err != nil {
			// 处理更新错误
			return response.FailResult(1, err.Error(), ctx)

		}
		util.TaskSetTimeUrl = req.SystemInfo.TaskSetTimeUrl
	}
	return response.SuccessResultWithEmptyData(ctx)
}

func GETVersion(ctx echo.Context) error {
	return response.SuccessResult(util.Version, ctx)
}

// 下载数据库
// func ExportHandler(c echo.Context) error {
// 	// 指定SQLite3数据库文件路径
// 	dbPath := "gw0x_sl_db/gw0x.db"
// 	// 使用 exec.Command 函数创建命令对象
// 	cmd := exec.Command("sqlite3", dbPath, ".dump")

// 	// 执行命令并捕获输出
// 	output, err := cmd.CombinedOutput()
// 	if err != nil {
// 		return response.FailResult(1, "Error exporting database:"+err.Error(), c)
// 	}

// 	// 设置HTTP响应头，指定下载文件的名称
// 	c.Response().Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", "export.sql"))
// 	c.Response().Header().Set("Content-Type", "application/octet-stream")

// 	// 使用 Write 方法将导出内容直接写入 HTTP 响应
// 	c.Response().Write(output)

//		return response.SuccessResultWithEmptyData(c)
//	}
//
// 生成密令
func GetPassWord(ctx echo.Context) error {
	util.InitPassWord = generateRandomKey(8)
	return response.SuccessResult(util.InitPassWord, ctx)
}

// 恢复出厂设置 密令验证
func CheckPassWord(ctx echo.Context) error {
	var req models.CheckPassWord
	if err := ctx.Bind(&req); err != nil {
		// 处理参数绑定错误
		return response.FailResult(1, err.Error(), ctx)

	}
	if util.InitPassWord == "" {
		return response.FailResult(1, "密令未生成", ctx)
	} else {
		if util.InitPassWord == req.PassWord {
			//密令成功
			err := DeleteTable()
			if err != nil {
				return response.FailResult(1, "恢复出厂设置失败,err:"+err.Error(), ctx)
			}
			go pac.Reboot()
			return response.SuccessResult("已恢复出厂设置，并自动重启", ctx)
		} else {
			return response.FailResult(1, "密令验证失败", ctx)
		}
	}

}
func generateRandomKey(length int) string {
	rand.Seed(time.Now().UnixNano())

	// 定义字符集
	charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

	// 生成随机密钥
	key := make([]byte, length)
	for i := range key {
		key[i] = charset[rand.Intn(len(charset))]
	}

	return string(key)
}

// 删除所有表
func DeleteTable() error {
	db := db.GetDB()
	// 获取所有的表名
	tables := []string{}
	result := db.Raw("SELECT name FROM sqlite_master WHERE type='table';").Scan(&tables)
	if result.Error != nil {

		return result.Error
	}

	// 删除所有表
	for _, table := range tables {
		if table != "EthSetting" {
			result := db.Exec(fmt.Sprintf("DROP TABLE IF EXISTS %s;", table))
			if result.Error != nil {

				return result.Error
			}
		}

	}
	return nil
}
